#Region " WikiBot Class "

''' <summary>
''' Implements
''' </summary>
''' <remarks></remarks>
Public Class WikiBot

#Region " Shared Fields "

#End Region

#Region " Fields "

    Private m_UserAgent As String
    Private m_Site As WikiBotLib.WikiSite
    Private m_UserName As String
    Private m_UserPass As String
    Private m_Cookies As System.Net.CookieContainer

#End Region

#Region " Constructors "

    Public Sub New(ByVal userAgent As String, ByVal site As WikiBotLib.WikiSite)
        Me.New(userAgent, site, Nothing, Nothing)
    End Sub

    Public Sub New(ByVal userAgent As String, ByVal site As WikiBotLib.WikiSite, ByVal userName As String, ByVal userPass As String)
        MyBase.New()
        ' validate the parameters
        If (site Is Nothing) Then Throw New System.ArgumentNullException("site")
        ' copy the parameters locally
        m_UserAgent = userAgent
        m_Site = site
        m_UserName = userName
        m_UserPass = userPass
    End Sub

#End Region

#Region " Properties "

    Public ReadOnly Property UserAgent() As String
        Get
            Return m_UserAgent
        End Get
    End Property

    Public ReadOnly Property Site() As WikiSite
        Get
            Return m_Site
        End Get
    End Property

    Public ReadOnly Property UserName() As String
        Get
            Return m_UserName
        End Get
    End Property

    Public ReadOnly Property UserPass() As String
        Get
            Return m_UserPass
        End Get
    End Property

    Public ReadOnly Property Cookies() As System.Net.CookieContainer
        Get
            Return m_Cookies
        End Get
    End Property

#End Region

#Region " Methods "

    Public Sub Connect()
        ' logging in is a two-stage approach:
        '     1. connect with no cookies to get a new session identifier
        '     2. connect again with cookies to log in
        Dim strRequestUri As String
        Dim objRequest As System.Net.HttpWebRequest
        Dim strPostData As String
        Dim objPostDataBytes() As Byte
        Dim objResponse As System.Net.HttpWebResponse
        Dim objCookies As System.Net.CookieContainer
        Dim objResponseStream As System.IO.Stream
        Dim objResponseReader As System.IO.StreamReader
        Dim strResponseBody As String
        ' build the uri to query
        strRequestUri = String.Empty
        strRequestUri = strRequestUri & Me.Site.SiteUrl
        If Not (Me.Site.IndexPath = String.Empty) Then
            strRequestUri = strRequestUri & "/" & Me.Site.IndexPath
        End If
        strRequestUri = strRequestUri & "/index.php?"
        strRequestUri = strRequestUri & "title=Special:Userlogin"
        strRequestUri = strRequestUri & "&action=submitlogin"
        strRequestUri = strRequestUri & "&type=login"
        ' build the data to post
        strPostData = String.Format("wpName={0}&wpPassword={1}&wpLoginattempt&wpRemember=1&Log+in", UserName, UserPass)
        objPostDataBytes = System.Text.Encoding.UTF8.GetBytes(strPostData)
        ' build the request with no cookies
        objRequest = CType(System.Net.HttpWebRequest.Create(New Uri(strRequestUri)), System.Net.HttpWebRequest)
        objRequest.AllowAutoRedirect = False
        objRequest.Headers.Add("Cache-Control", "no-cache")
        objRequest.Headers.Add("Pragma", "no-cache")
        objRequest.Method = "GET"
        objRequest.ContentType = "application/x-www-form-urlencoded"
        objRequest.UserAgent = Me.UserAgent
        objRequest.CookieContainer = New System.Net.CookieContainer
        ' check we get a redirect otherwise login has failed
        objResponse = Me.Site.ExecuteRequest(objRequest)
        If Not (objResponse.StatusCode = Net.HttpStatusCode.OK) Then
            Throw New System.InvalidOperationException("login failed")
        End If
        ' get the cookies from the response so we know what to send back
        objCookies = New System.Net.CookieContainer
        For Each cookie As System.Net.Cookie In objResponse.Cookies
            objCookies.Add(cookie)
        Next cookie
        objResponse.Close()
        ' repeat the request again, using the cookies this time
        objRequest = CType(System.Net.HttpWebRequest.Create(New Uri(strRequestUri)), System.Net.HttpWebRequest)
        objRequest.AllowAutoRedirect = False
        objRequest.Headers.Add("Cache-Control", "no-cache")
        objRequest.Headers.Add("Pragma", "no-cache")
        objRequest.Method = "POST"
        objRequest.ContentType = "application/x-www-form-urlencoded"
        objRequest.UserAgent = Me.UserAgent
        objRequest.CookieContainer = objCookies
        ' get the response
        objResponse = Me.Site.ExecuteRequest(objRequest, objPostDataBytes)
        objResponseStream = objResponse.GetResponseStream
        objResponseReader = New System.IO.StreamReader(objResponseStream)
        strResponseBody = objResponseReader.ReadToEnd
        objResponseReader.Close()
        objResponse.Close()
        ' check we get an ok otherwise login has failed
        If Not (objResponse.StatusCode = Net.HttpStatusCode.OK) Then
            Throw New System.InvalidOperationException("login failed")
        End If
        ' make sure the user was logged in
        If (strResponseBody.IndexOf("var wgUserName = """ & UserName & """;") = -1) Then
            Throw New System.InvalidOperationException("login failed")
        End If
        ' remember the cookies for subsequent requests
        m_Cookies = objCookies
    End Sub

    Public Function GetPageHistory(ByVal title As String, ByVal limit As Integer) As WikiBotLib.WikiPageCollection
        Return Me.Site.GetPageHistory(Me.Cookies, title, limit)
    End Function

    Public Function GetPageHistory(ByVal title As String, ByVal limit As Integer, ByVal getBody As Boolean) As WikiBotLib.WikiPageCollection
        Return Me.Site.GetPageHistory(Me.Cookies, title, limit, getBody)
    End Function

    Public Function GetPageBody(ByVal title As String) As String
        Return Me.Site.GetPageBody(Me.Cookies, title)
    End Function

    Public Sub SavePage(ByVal page As WikiPage, ByVal summary As String, ByVal minor As Boolean, ByVal watchThis As Boolean)
        Me.Site.SavePage(Me.Cookies, page, summary, minor, watchThis)
    End Sub

    Public Sub SavePage(ByVal title As String, ByVal body As String, ByVal summary As String, ByVal minor As Boolean, ByVal watchThis As Boolean)
        Me.Site.SavePage(Me.Cookies, title, body, summary, minor, watchThis)
    End Sub

    Public Function GetSpecialUncategorizedImages(ByVal limit As Integer) As WikiBotLib.WikiPageCollection
        Return Me.Site.GetSpecialUncategorizedImages(Me.Cookies, limit)
    End Function

    Public Sub UploadImage(ByVal sourceFilePath As String, ByVal targetFileName As String, ByVal description As String, ByVal license As String, ByVal watchThis As Boolean, ByVal contentType As String)
        ' get the source file bytes
        Dim objStream As System.IO.FileStream
        Dim objFileBytes() As Byte
        objStream = New System.IO.FileStream(sourceFilePath, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
        ReDim objFileBytes(CType(objStream.Length, Integer) - 1)
        objStream.Read(objFileBytes, 0, CType(objStream.Length, Integer))
        objStream.Close()
        ' upload the file
        Me.Site.UploadImage(Me.Cookies, targetFileName, description, license, watchThis, objFileBytes, contentType)
    End Sub

    Public Function GetSpecialWhatLinksHere(ByVal title As String, ByVal limit As Integer) As WikiPageCollection
        Return Me.Site.GetSpecialWhatLinksHere(Me.Cookies, title, limit)
    End Function

    Public Function ApiQueryImageInfo(ByVal title As String) As WikiPageCollection
        Return Me.Site.ApiQueryImageInfo(Me.Cookies, title)
    End Function

#End Region

End Class

#End Region
